<?php
/**
 * Zhub - A PHP Framework For API Developer
 *
 * This file is part of the Zhub package.
 *
 * (c) YiLong Fan <fantiq@163.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @author fanyilong <fantiq@163.com>
 * @copyright 2017 fanyilong. All rights reserved.
 * @package Zhub
 * @date 18-3-15
 */

namespace Zhub\Swoole\Server\Http;


use Zhub\Application\Http\Server\HttpServer;
use Zhub\DataStruct\Maps\StringMap;
use Zhub\HttpMessage\Headers\RequestHeader;
use Zhub\HttpMessage\Request;
use Zhub\HttpMessage\RequestMethod;
use Zhub\HttpMessage\Response;
use Zhub\Uri\Url\Url;
use Zhub\Uri\Url\UrlStruct;

class SwooleHttpServer implements HttpServer
{
    private $request = null;

    private $response = null;

    public function __construct($request, $response)
    {
        $this->request = $request;

        $this->response = $response;
    }

    public function getRequest(): Request
    {
        list(, $protocolVersion) = explode('/', $this->getServer('SERVER_PROTOCOL', 'HTTP/1.1'));

        $body = $this->request->rawContent();

        return new Request([
            Request::METHOD => RequestMethod::id($this->getServer('REQUEST_METHOD', 'GET')),
            Request::URL => $this->getUrl(),
            Request::PROTOCOL_VERSION => $protocolVersion,
            Request::HEADER => $this->getHeader(),
            Request::BODY => $body ? $body : '',
        ]);
    }

    public function getHeader(): RequestHeader
    {
        $headers = [];

        foreach ($this->request->header as $key => $val) {
            $headers[ucwords($key, '-')] = $val;
        }
        return new RequestHeader([
            RequestHeader::HEADER => new StringMap($headers),
            RequestHeader::COOKIE => new StringMap($this->request->cookie??[])
        ]);
    }

    public function getUrl(): UrlStruct
    {
        return Url::build([
            UrlStruct::SCHEME => 'http',
            UrlStruct::HOST => $this->getServer('HTTP_HOST'),
            UrlStruct::PORT => intval($this->getServer('SERVER_PORT', 0)),
            UrlStruct::PATH => $this->getServer('REQUEST_URI', '/'),
            UrlStruct::QUERY => $this->getServer('QUERY_STRING', ''),
        ]);
    }

    public function getServer(string $key = null, $def = null)
    {
        $server = $this->request->server;
        return $key == null ? $server :
            ($server[$key] ?? ($server[strtolower($key)]??$def));
    }

    public function handleResponse(Response $response)
    {
        $this->response->end($response->getBody());
    }

}
